package se.webbzon.boltzmann.game.object.pickup;

import java.util.Collection;

import se.webbzon.boltzmann.collector.Collector;
import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.boltzmann.game.environment.GameEnvironment;
import se.webbzon.boltzmann.game.object.player.AbstractPlayerCharacter;
import se.webbzon.boltzmann.game.region.RegionObject;
import se.webbzon.boltzmann.player.PlayerCoins;
import se.webbzon.boltzmann.player.PlayerEnergy;
import se.webbzon.boltzmann.player.PlayerHealth;
import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldeditor.DeflatableWorldObject;
import se.webbzon.oschi01.worldeditor.WorldObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.XYPlaneAppearance3D;

public class Pickup extends WorldStaticObject implements DeflatableWorldObject, RegionObject { 
	
	// The name of this deflatable world object
	public static final String worldObjectName = "pickup";
	
	// The range of this pickup
	private static final double pickupDistance = 16;
	
	// The environment of this pickup
	private final AbstractEnvironment env;
	
	// The shadow of this pickup
	private final PickupShadow shadow;
	
	// A collector used to track all the players in the world
	private Collector<AbstractPlayerCharacter> players;
	
	// The id of this region object
	private long id;
	
	// The pickup type
	private PickupEnum type;
	
	/*============================================================
	Constructors
	============================================================*/

	/** Creates a new pickup with a given id and type. **/
	public Pickup(AbstractEnvironment env, long id, PickupEnum type) {
		super(	WorldObject.onCreate + WorldObject.onStep + WorldObject.onDestroy, 
				createAppearance(type));
		this.env = env;
		this.id = id;
		setType(type);
		
		shadow = new PickupShadow(this);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Sets the pickup type. **/
	public PickupEnum getType() {
		return type;
	}

	/** Returns the pickup type. **/
	public void setType(PickupEnum type) {
		final String textureSetName;
		switch (type) {
		case SILVER_COIN: textureSetName = "pickup_silver_coin"; break;
		case GOLD_COIN: textureSetName = "pickup_gold_coin"; break;
		case HEALTH: textureSetName = "effect_health_drop"; break;
		case ENERGY: textureSetName = "effect_energy_drop"; break;
		default: textureSetName = "";
		}
		
		if (!textureSetName.isEmpty()) {
			SimpleAppearance3D appearance = (SimpleAppearance3D) getAppearance();
			appearance.setTextureSet(Resources.getTextureSet(textureSetName));
			this.type = type;
		}
	}

	@Override public long getId() {
		return id;
	}

	@Override public void setId(long id) {
		this.id = id;
	}
	
	@Override public void onCreate(WorldArea world) {
		players = Collector.getCollector(world, AbstractPlayerCharacter.class);
		shadow.launch(world);
	}

	@Override public void onStep(WorldArea world) {
		Collection<AbstractPlayerCharacter> playerCollection = players.getInstances();
		synchronized (playerCollection) {
			for (AbstractPlayerCharacter player : playerCollection) {
				if (distanceTo(player) <= pickupDistance) {
					
					PlayerCoins coins = player.getPlayer().getCoins(); 
					PlayerHealth health = player.getPlayer().getHealth();
					PlayerEnergy energy = player.getPlayer().getEnergy();
					if (type == PickupEnum.GOLD_COIN) {
						coins.setCoins(coins.getCoins() + 5);
					} else if (type == PickupEnum.SILVER_COIN) {
						coins.setCoins(coins.getCoins() + 1);
					} else if (type == PickupEnum.HEALTH) {
						health.setHealth(health.getHealth() + 1);
					} else {
						energy.setEnergy(energy.getEnergy() + 1);
					}
					
					if (env instanceof GameEnvironment)
						((GameEnvironment) env).addRegionPersistence(this);
					
					world.destroyInstance(this);
					break;
				}
			}
		}
	}

	@Override public void onDestroy(WorldArea world) {
		players = null;
		shadow.terminate(world);
	}

	@Override public String getName() {
		return worldObjectName;
	}

	@Override public WorldObjectDeflation getDeflation() {
		return new PickupDeflation(0,this);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the appearance of this pickup. **/
	private static final Appearance3D createAppearance(PickupEnum type) {
		XYPlaneAppearance3D appearance = new XYPlaneAppearance3D();
		appearance.setTextureSpeed(0.5);
		return appearance;
	}

}
